package com.minisoft.utils;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ReflectUtil;
import com.minisoft.entity.CounterField;
import com.minisoft.entity.TagField;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

public class CommonUtil {
    /**
     * 判断对象或对象数组中每一个对象是否为空: 对象为null，字符序列长度为0，集合类、Map为empty
     *
     * @return true or false
     * @author chenjl
     */
    public static boolean isNullOrEmpty(Object obj) {
        if (obj == null) {
            return true;
        }

        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        }

        if (obj instanceof Collection) {
            return ((Collection) obj).isEmpty();
        }

        if (obj instanceof Map) {
            return ((Map) obj).isEmpty();
        }

        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            boolean empty = true;
            for (Object anObject : object) {
                if (!isNullOrEmpty(anObject)) {
                    empty = false;
                    break;
                }
            }
            return empty;
        }
        return false;
    }

    /**
     * 统计属性完成度
     * @param obj
     * @return 完成度百分比
     */
    public static String countField(Object obj) {
        Field[] fields = ReflectUtil.getFields(obj.getClass());
        float total = 0,completeTotal = 0;
        String percent = null;
        for (Field field : fields) {
            if (field.isAnnotationPresent(CounterField.class)) {
                total++;
                Object value = getFieldValue(obj, field);
                if (!isNullOrEmpty(value)) {
//                    System.out.println("field="+field.getName()+",value="+value);
                    completeTotal++;
                }
            }
        }
        if (total > 0) {
            percent = NumberUtil.formatPercent(completeTotal/total,0);
        }
        return percent;
    }

    /**
     * 把类中有TagField的属性提取出来
     * @param obj
     * @return
     */
    public static List<String> extractTags(Object obj) {
        Field[] fields = ReflectUtil.getFields(obj.getClass());
        List<String> tags = new ArrayList<>();
        for (Field field : fields) {
            if (field.isAnnotationPresent(TagField.class)) {
                Object value = getFieldValue(obj, field);
                if (!isNullOrEmpty(value)) {
                    tags.add(value.toString());
                }
            }
        }
        return tags;
    }

    private static Object getFieldValue(Object obj, Field field) {
        Object value = null;
        field.setAccessible(true);
        try {
            // try to get value from getter method
            String fieldName = field.getName();
            String getterName;
            if (field.getType() == boolean.class || field.getType() == Boolean.class) {
                if (fieldName.startsWith("is")) {
                    getterName = fieldName;
                } else {
                    getterName = "is" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
                }
            } else {
                getterName = "get" + fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
            }
            Method getter = obj.getClass().getMethod(getterName);
            value = getter.invoke(obj);
        } catch (Exception e) {
            // ignore
        }
        if (value == null) {
            try {
                value = field.get(obj);
            } catch (Exception e) {
            }
        }
        return value;
    }
}
